package com.sghd.candy.module.player.manager;

import com.fasterxml.jackson.core.type.TypeReference;
import com.sghd.common.ramcache.IEntity;
import com.sghd.common.ramcache.PerPersist;
import com.sghd.common.ramcache.anno.Cached;
import com.sghd.common.ramcache.anno.CachedSizes;
import com.sghd.common.ramcache.anno.Persister;
import com.sghd.common.ramcache.anno.Persisters;
import com.sghd.common.ramcache.enhance.Enhance;
import com.sghd.common.utils.json.JsonUtils;

import javax.persistence.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Allen
 * @date 2019/01/10
 */
@Entity
@Table(catalog = "bsdld")
@Cached(size = CachedSizes.DEFAULT, persister = @Persister(Persisters.PRE_10_MINUTE))
public class PlayerOther implements IEntity<Long>, PerPersist {
    @Id
    private Long playerId;
    @Transient
    private volatile Map<String, String> contents;
    @Lob
    private String contentsJson;

    public static PlayerOther valueOf(long playerId) {
        PlayerOther playerOther = new PlayerOther();
        playerOther.setPlayerId(playerId);
        playerOther.setContents(new HashMap<>(1));
        return playerOther;
    }

    public Long getPlayerId() {
        return playerId;
    }

    public void setPlayerId(Long playerId) {
        this.playerId = playerId;
    }

    public Map<String, String> getContents() {
        return contents;
    }

    public void setContents(Map<String, String> contents) {
        this.contents = contents;
    }

    public String getContentsJson() {
        return contentsJson;
    }

    public void setContentsJson(String contentsJson) {
        this.contentsJson = contentsJson;
    }

    public synchronized <T> T getContent(String key, Class<T> clz) {
        String json = contents.get(key);
        if (clz.equals(String.class)) {
            return (T) json;
        }
        if (json != null) {
            return JsonUtils.string2Object(json, clz);
        } else {
            return null;
        }
    }

    public synchronized <T> T getContent(String key, T defaultValue, Class<T> clz) {
        String json = contents.get(key);
        if (clz.equals(String.class)) {
            return (T) json;
        }
        if (json != null) {
            return JsonUtils.string2Object(json, clz);
        } else {
            return defaultValue;
        }
    }

    /**
     * 转换泛型对象
     */
    public synchronized <T> T getValue(String key, TypeReference<T> typeReference) {
        String json = contents.get(key);
        if (json == null) {
            return null;
        }
        return JsonUtils.string2GenericObject(json, typeReference);
    }

    @Enhance
    synchronized void setContent(String key, String content) {
        contents.put(key, content);
    }

    @Override
    public Long getId() {
        return this.playerId;
    }

    @Override
    public void afterLoad() {
        contents = JsonUtils.string2Map(contentsJson, String.class, String.class);
    }

    @Override
    public void beforePersist() {
        contentsJson = JsonUtils.object2String(contents);
    }
}
